;;;; init-package  安装配置 elpa 插件

;;---------------------------------------------------------------------
;; ;; 测试启动耗时
;; ;; M-x benchmark-init/show-durations-tree 或者 M-x benchmark-init/show-durations-tabulated 显示耗时
(use-package benchmark-init
  :init (benchmark-init/activate)
  :hook (aer-init . benchmark-init/deactivate))
;;---------------------------------------------------------------------

;;---------------------------------------------------------------------
;; emacs 自带插件
;; 使用use-package 推迟加载一些模式

;;{{ dired-mode
;; 配置 dired-mode
;; (add-hook 'dired-mode-hook
;;           (lambda ()
;;             (local-unset-key (kbd "<SPC>")))) ; 注销 spc 键, 留给 leader 键
;; dired-mode}}

;; 最近打开文件设置
(use-package recentf
  :defer 2
  :config
  (setq recentf-max-menu-items 10
        recentf-max-saved-items 365)
  )
;(global-set-key (kbd "C-x C-r") 'recentf-open-files) ; 已使用counsel-recnetf

(use-package emacs
  :defer 4
  :config
  (winner-mode t) ; 窗口管理 undo redo
  (show-paren-mode t) ;括号匹配高亮
  (global-font-lock-mode t)    ;语法高亮
  (auto-image-file-mode t) ;打开图片显示功能
  (electric-pair-mode 1) ; 闭括号自动完成
  (save-place-mode 1) ; 保存上次编辑文件的位置
  (global-auto-revert-mode t) ;自动载入磁盘上发生变更的文件
  ;; buffer name 唯一
  ;; meaningful names for buffers with the same name
  ;; from prelude
  ;; https://github.com/bbatsov/prelude
  (require 'uniquify)
  (setq uniquify-buffer-name-style 'forward)
  (setq uniquify-separator "/")
  (setq uniquify-after-kill-buffer-p t)    ; rename after killing uniquified
  (setq uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers
  )

;; {{whitespace
;;  https://github.com/condy0919/emacs-newbie/blob/master/introduction-to-builtin-modes.md
(use-package whitespace
  :ensure nil
;  :hook ((prog-mode markdown-mode conf-mode) . whitespace-mode)
  :commands (whitespace-mode)
  ;; :custom (whitespace-line-column 78)
  ;;         (fill-column 78)
  :config
  (setq whitespace-line-column 78
        fill-column 78)
  ;; Don't use different background for tabs.
  (face-spec-set 'whitespace-tab
                 '((t :background unspecified)))
  ;; Only use background and underline for long lines, so we can still have
  ;; syntax highlight.

  ;; For some reason use face-defface-spec as spec-type doesn't work.  My guess
  ;; is it's due to the variables with the same name as the faces in
  ;; whitespace.el.  Anyway, we have to manually set some attribute to
  ;; unspecified here.
  (face-spec-set 'whitespace-line
                 '((((background light))
                    :background "#d8d8d8" :foreground unspecified
                    :underline t :weight unspecified)
                   (t
                    :background "#404040" :foreground unspecified
                    :underline t :weight unspecified)))

  ;; Use softer visual cue for space before tabs.
  (face-spec-set 'whitespace-space-before-tab
                 '((((background light))
                    :background "#d8d8d8" :foreground "#de4da1")
                   (t
                    :inherit warning
                    :background "#404040" :foreground "#ee6aa7")))

  (setq
   whitespace-line-column nil
   whitespace-style
   '(face             ; visualize things below:
     empty            ; empty lines at beginning/end of buffer
     lines-tail       ; lines go beyond `fill-column'
     space-before-tab ; spaces before tab
     trailing         ; trailing blanks
     tabs             ; tabs (show by face)
     tab-mark         ; tabs (show by symbol)
     )))
;; whitespace}}

(use-package whitespace-cleanup-mode
  ;; https://github.com/purcell/whitespace-cleanup-mode
  ;; 和 emacs 自身的 whitespace-cleanup 命令 不是一个东西
  :hook(after-init . global-whitespace-cleanup-mode)
  :config
  (diminish 'whitespace-cleanup-mode)
  ;; https://www.cnblogs.com/rex-tech/p/3582646.html
  ;; makfile 文件 使用 <tab> 关闭 whitespace-cleanup-mode
  ;; 并设置 tab-width 8
  (add-hook 'makefile-mode-hook
          (lambda ()
            (whitespace-cleanup-mode 0)
            (setq tab-width 8)))
  )


;;---------------------------------------------------------------------

;;---------------------------------------------------------------------
;; unicad  site-lisp/
;; https://www.emacswiki.org/emacs/Unicad
(use-package unicad
  ;;:ensure nil
  :defer 4)

;;---------------------------------------------------------------------

;;---------------------------------------------------------------------
;; pasteex-mode windows系统下, 第三方命令行 pasteex 插入剪贴板图片
;; https://github.com/dnxbjyj/pasteex-mode
;; https://github.com/huiyadanli/PasteEx/wiki
(use-package pasteex-mode
  :ensure nil
  :commands (pasteex-image)
  ;; :config
  ;; (iimage-mode)
  )

;;---------------------------------------------------------------------



;;---------------------------------------------------------------------
;; org-anki
;; https://github.com/eyeinsky/org-anki
(use-package org-anki
  :defer 4
  :config
  (customize-set-variable 'org-anki-default-deck "org-anki-test-deck")
  )

;;---------------------------------------------------------------------

;;---------------------------------------------------------------------
;;主题配置
(use-package solarized-theme
  :init ; 进行加载配置
  (load-theme 'solarized-dark t)
 ;(load-theme 'solarized-light t) ; 亮色主题
  )

;;---------------------------------------------------------------------

;;---------------------------------------------------------------------
;; diminish ets you fight modeline clutter by removing or
;; abbreviating minor mode indicators.
(use-package diminish)
;;---------------------------------------------------------------------

;;---------------------------------------------------------------------
;; 窗口管理
(use-package window-numbering
  :defer 2
  :config
  (window-numbering-mode 1)
  )

;;---------------------------------------------------------------------

;;---------------------------------------------------------------------
;; ivy counsel swiper 三剑客
;;https://github.com/abo-abo/swiper
(use-package ivy
  ;:defer 1
  :hook (after-init . ivy-mode)
  :config
  (ivy-mode 1)
  (diminish 'ivy-mode)
  (setq ivy-use-virtual-buffers t
        ivy-initial-inputs-alist nil
        ivy-count-format "%d/%d "
        enable-recursive-minibuffers t
        ivy-re-builders-alist
        '((t . ivy--regex-plus)
          (read-file-name-internal . ivy--regex-fuzzy);;;模糊正则补全
          (counsel-M-x . ivy--regex-fuzzy)
          ))
  )

; Ivy sorts such large lists using flx package's scoring mechanism, if it's installed.
(use-package flx
  :after ivy
  :defer 2)

(use-package counsel
  :after (ivy)
  :bind (("M-x" . counsel-M-x)
         ("C-x C-f" . counsel-find-file)
         ("C-x C-r" . counsel-recentf)
         ("C-h f" . counsel-describe-function)
         ("C-h v" . counsel-describe-variable)
         ("C-c g" . counsel-git)))

(use-package swiper
  :after ivy
  :bind (("C-s" . swiper)
        ; ("C-r" . swiper-isearch-backward) ; evil-mode 被占用, 改为 SPC sb
         )
  :config (setq swiper-action-recenter t
                swiper-include-line-number-in-search t))
;; windows系统下，find-file 到其它盘符文件，删除到行首后，直接在d:/后按 "c:/"，会自动修正路径
;;---------------------------------------------------------------------

;;---------------------------------------------------------------------
;;自动补全
(use-package company
  :config
  (setq company-backends
        '((company-files ; files & directory
           company-keywords
           ;; company-gtags
           ;; company-etags
           company-elisp
           company-capf ; completion-at-point-functions
           company-yasnippet
           company-abbrev
           company-dabbrev)
          ))
  (setq company-dabbrev-code-everywhere t
        company-dabbrev-code-modes t
        company-dabbrev-code-other-buffers 'all
        company-dabbrev-other-buffers 'all
        company-dabbrev-char-regexp "\\sw\\([_-]\\w\\)*"  ; _-连接的单词也被补全
        company-dabbrev-downcase nil
        company-dabbrev-ignore-case t
        company-dabbrev-minimum-length 3
        company-require-match nil
        company-minimum-prefix-length 3 ; 最小补全长度
        company-show-numbers t
        company-tooltip-limit 20
        company-idle-delay 0.3 ;停留0.3秒开始补全
        company-echo-delay 0
        company-tooltip-offset-display 'scrollbar
        company-begin-commands '(self-insert-command))
  ;; (push '(company-semantic :with company-yasnippet) company-backends)
  ;;:hook ((after-init . global-company-mode)) ; 所有mode都启动company
  :hook ((prog-mode
          LaTeX-mode
          ;; markdown-mode
          org-mode) . company-mode)
    ) ; use-package company-mode end here

;; https://emacs.stackexchange.com/questions/15246/how-add-company-dabbrev-to-the-company-completion-popup

;; ;; 特殊
;; (add-hook 'python-mode-hook
;;    (lambda ()
;; (set (make-local-variable 'company-backends) '(company-anaconda))))

;; If your want to remove/add backends instead of tweaking the priority of backends.
;;https://emacs.stackexchange.com/questions/20485/how-to-exclude-a-company-backend-from-autocompleting-without-globally-removing-i
;; (defun company-my-setup ()
;;   (when (boundp 'company-backends)
;;     (make-local-variable 'company-backends)
;;     ;; remove
;;     (setq company-backends (delete 'company-dabbrev company-backends))
;;     ;; add
;;     (add-to-list 'company-backends 'company-dabbrev)
;;     ))

;; (add-hook 'latex-major-mode-hook 'company-my-setup)

;;---------------------------------------------------------------------

;;---------------------------------------------------------------------
;;中文首字母拼音跳转, 需avy 支持
(use-package ace-pinyin)

;; avy 跳转
;; https://github.com/abo-abo/avy/
(use-package avy
  :commands (avy-goto-char-2) ; init-evil中定义 SPC av 调用命令
  )

;; 加载avy后, 加载ace-pinyin
(with-eval-after-load 'avy
  (require 'ace-pinyin)
  (ace-pinyin-global-mode 1)
  ;;禁止ace-pinyin在mode-line 显示
  ;;删掉minor-mode-alist 列表中ace-pinyin
  ;; (setq minor-mode-alist (remove '(ace-pinyin-mode " AcePY")
  ;;                              minor-mode-alist))
  (diminish 'ace-pinyin-mode)
  )

;;---------------------------------------------------------------------

;;---------------------------------------------------------------------
;; expand reigon
;; https://github.com/magnars/expand-region.el
(use-package expand-region
  ;:bind ("C-=" . er/expand-region) ; init-evil 中设置键绑定
  )

;;---------------------------------------------------------------------

;;---------------------------------------------------------------------
;; markdown-mode
;; https://github.com/jrblevin/markdown-mode
(use-package markdown-mode
  :hook (markdown-mode . iimage-mode)
  :mode (("README\\.md\\'" . gfm-mode)
         ("\\.md\\'" . markdown-mode)
         ("\\.markdown\\'" . markdown-mode))
  )
;; (autoload 'markdown-mode "markdown-mode"
;;    "Major mode for editing Markdown files" t)
;; (add-to-list 'auto-mode-alist
;;              '("\\.\\(?:md\\|markdown\\|mkd\\|mdown\\|mkdn\\|mdwn\\)\\'" . markdown-mode))

;; (autoload 'gfm-mode "markdown-mode"
;;    "Major mode for editing GitHub Flavored Markdown files" t)
;; (add-to-list 'auto-mode-alist '("README\\.md\\'" . gfm-mode))

(use-package markdown-toc
  ;; https://github.com/ardumont/markdown-toc
  :commands(markdown-toc-generate-toc
            markdown-toc-generate-or-refresh-toc
            markdown-toc-refresh-toc
            markdown-toc-delete-toc
             )
  )
;;---------------------------------------------------------------------


;;---------------------------------------------------------------------
;; org markdown 中英文混合对齐, 适用于 GUI emacs
;; https://github.com/casouri/valign   2020-10-13
;; https://emacs-china.org/t/org-mode/13248
;; 基本原理是：algin-to这个text property，可以生成对齐到某个像素位置
;; 的空白。终端Emacs不可能的，只能靠等宽字体。支持变宽字体，汉字，图片

(use-package valign
  ;; 手动存放在 site-lisp/valign
  :ensure nil
  :init
  ;; (add-hook 'org-mode-hook #'valign-mode))
  :hook ((org-mode markdown-mode) . valign-mode)
  )
;;---------------------------------------------------------------------


;;---------------------------------------------------------------------
;; yasnippet

;;https://github.com/AndreaCrotti/yasnippet-snippets
;; 模板仓库
(use-package yasnippet-snippets
  :after yasnippet
  :defer 3
   )

;; https://github.com/joaotavora/yasnippet
(use-package yasnippet
  :hook ((emacs-lisp-mode
          markdown-mode
          org-mode
          python-mode
          js-mode
          LaTeX-mode ; AucTeX
       ;;   ) .   yas-minor-mode) ;使用 minor-mode, 会造成自定义模板目录失效, 原因不明
		  ) .   yas-global-mode)
  :config
  ;; 仓库地址默认已经是下面两个目录
  ;; (setq yas-snippet-dirs
  ;;       '("~/.emacs.d/snippets"  ;个人模板仓库
  ;;         yas-installed-snippets-dir ;自动找到下载的仓库地址
  ;;       ))
  :bind(:map yas-minor-mode-map
             ("<tab>" . nil)
             ;; ("C-c <tab>" . yas-expand)
             ;; ("<C-tab>" . yas-next-field)
             ("<C-tab>" . yas-expand)
             )
  )
;;---------------------------------------------------------------------
                                        ;-

;;---------------------------------------------------------------------
;; elpa-mirror site-lisp
(use-package elpa-mirror
  :ensure nil
  :commands (elpamr-create-mirror-for-installed)
  )

;;---------------------------------------------------------------------


;;---------------------------------------------------------------------
;; https://github.com/technomancy/find-file-in-project
(use-package find-file-in-project
  :commands (find-file-in-project
             )
  )


;;---------------------------------------------------------------------

;;---------------------------------------------------------------------
;;https://github.com/justbur/emacs-which-key
(use-package which-key
  :defer 2
  :config
  (which-key-mode)
  (diminish 'which-key-mode)
  )
;;---------------------------------------------------------------------

;;---------------------------------------------------------------------
;; wgrep
;; https://github.com/mhayashi1120/Emacs-wgrep
;; cousel-rg  绑定到 <spc>rg
;; C-c C-o  ivy-occur
;; C-x C-q  ivy-wgrep-change-to-wgrep-mode
;; C-c C-c （wgrep-finish-edit）
;; C-c C-k 取消修改

(use-package wgrep
  :hook (ivy-occur-mode . wgrep))
;;---------------------------------------------------------------------


;;---------------------------------------------------------------------
;; wucuo
;; https://github.com/redguardtoo/wucuo
;; Please install either Aspell or Hunspell and the dictionaries at first.

(use-package wucuo
  ;; :hook ((text-mode prog-mode) . wucuo-start)
  :init
  ;; (setq ispell-program-name "c:/cygwin64/bin/hunspell.exe")
  ;; ;; http://gromnitsky.blogspot.com/2016/09/emacs-251-hunspell.html
  ;; (setq ispell-hunspell-dict-paths-alist
  ;;       '(("en_US" "C:/cygwin64/usr/share/myspell/en_US.aff")
  ;;         ("en_GB" "C:/cygwin64/usr/share/myspell/en_GB.aff")))

  ;; (setq ispell-local-dictionary "en_US")
  ;; (setq ispell-local-dictionary-alist
  ;;       '(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US") nil utf-8)))
  (setq ispell-program-name "aspell")
  ;; You could add extra option "--camel-case" for since Aspell 0.60.8
  ;; @see https://github.com/redguardtoo/emacs.d/issues/796
  (setq ispell-extra-args '("--sug-mode=ultra" "--lang=en_US" "--camel-case" "--run-together" "--run-together-limit=16"))
  )



;;---------------------------------------------------------------------


(provide 'init-packages)
